package com.lagou.handler;

import com.lagou.config.BoundSql;
import com.lagou.pojo.MappedStatement;
import com.lagou.utils.ClassUtil;
import com.lagou.mapping.ParameterMapping;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * 参数处理器的实现类
 * @author zhengzc
 * @version 1.0.0
 * @date 2020/2/24 16:06
 */
public class DefaultParameterHandler implements ParameterHandler {
    private final MappedStatement mappedStatement;
    private final Object[] parameterObject;
    private final BoundSql boundSql;

    /**
     * 默认构造器
     * @param mappedStatement sql封装类
     * @param parameterObject sql参数
     * @param boundSql 可执行sql
     */
    public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        this.mappedStatement = mappedStatement;
        this.parameterObject = (Object[]) parameterObject;
        this.boundSql = boundSql;
    }

    @Override
    public void setParameters(PreparedStatement preparedStatement) throws SQLException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
        String parameterType = mappedStatement.getParameterType();//参数类型
        Class<?> parameterTypeClass = ClassUtil.getClassType(parameterType);

        List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();
        for (int i = 0; i < parameterMappingList.size(); i++) {
            ParameterMapping parameterMapping = parameterMappingList.get(i);
            String content = parameterMapping.getContent();
            TypeHandlerRegistry registry = new TypeHandlerRegistry();
            if (registry.isBasicType(parameterTypeClass)){
                preparedStatement.setObject(i+1,parameterObject[0]);
            }else {
                //反射
                Field declaredField = parameterTypeClass.getDeclaredField(content);
                //暴力访问
                declaredField.setAccessible(true);
                Object o = declaredField.get(parameterObject[0]);

                preparedStatement.setObject(i+1,o);
            }
        }
    }


}
